package com.supercube.system.service.impl;

import com.github.pagehelper.PageHelper;
import com.supercube.common.utils.CubeUtils;
import com.supercube.common.utils.ShiroUtils;
import com.supercube.system.dao.RoleDao;
import com.supercube.system.dao.RoleMenuDao;
import com.supercube.system.dao.UserDao;
import com.supercube.system.dao.UserRoleDao;
import com.supercube.system.domain.RoleDO;
import com.supercube.system.domain.RoleMenuDO;
import com.supercube.system.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;


@Service
public class RoleServiceImpl implements RoleService {

    public static final String ROLE_ALL_KEY = "\"role_all\"";

    public static final String DEMO_CACHE_NAME = "role";

    @Autowired
    RoleDao roleMapper;
    @Autowired
    RoleMenuDao roleMenuMapper;
    @Autowired
    UserDao userMapper;
    @Autowired
    UserRoleDao userRoleMapper;

    @Override
    public List<RoleDO> list(Map<String, Object> map) {
        CubeUtils.startPage(map);
        List<RoleDO> roles = roleMapper.list(map);
        return roles;
    }

    @Override
    public List<RoleDO> list() {
        List<RoleDO> roles = roleMapper.list(new HashMap<>(16));
        return roles;
    }


    @Override
    public List<RoleDO> list(Long userId) {
        List<Long> rolesIds = userRoleMapper.listRoleId(userId);
        List<RoleDO> roles = roleMapper.list(new HashMap<>(16));
        for (RoleDO roleDO : roles) {
            roleDO.setRoleSign("false");
            for (Long roleId : rolesIds) {
                if (Objects.equals(roleDO.getRoleId(), roleId)) {
                    roleDO.setRoleSign("true");
                    break;
                }
            }
        }
        return roles;
    }

    @Transactional
    @Override
    public int save(RoleDO role) {
        Long userId = ShiroUtils.getUserId();
        role.setUserIdCreate(userId);
        int count = roleMapper.save(role);
        List<Long> menuIds = role.getMenuIds();
        Long roleId = role.getRoleId();
        List<RoleMenuDO> rms = new ArrayList<>();
        if (menuIds != null) {
            for (Long menuId : menuIds) {
                RoleMenuDO rmDo = new RoleMenuDO();
                rmDo.setRoleId(roleId);
                rmDo.setMenuId(menuId);
                rms.add(rmDo);
            }
        }
        roleMenuMapper.removeByRoleId(roleId);
        if (rms.size() > 0) {
            roleMenuMapper.batchSave(rms);
        }
        return count;
    }

    @Transactional
    @Override
    public int remove(Long id) {
        int count = roleMapper.remove(id);
        userRoleMapper.removeByRoleId(id);
        roleMenuMapper.removeByRoleId(id);
        return count;
    }

    @Override
    public RoleDO get(Long id) {
        RoleDO roleDO = roleMapper.get(id);
        return roleDO;
    }

    @Override
    public int update(RoleDO role) {
        int r = roleMapper.update(role);
        List<Long> menuIds = role.getMenuIds();
        Long roleId = role.getRoleId();
        roleMenuMapper.removeByRoleId(roleId);
        List<RoleMenuDO> rms = new ArrayList<>();
        if (menuIds != null) {
            for (Long menuId : menuIds) {
                RoleMenuDO rmDo = new RoleMenuDO();
                rmDo.setRoleId(roleId);
                rmDo.setMenuId(menuId);
                rms.add(rmDo);
            }
        }
        if (rms.size() > 0) {
            roleMenuMapper.batchSave(rms);
        }
        return r;
    }

    @Override
    public int batchremove(Long[] ids) {
        int r = roleMapper.batchRemove(ids);
        return r;
    }

    @Override
    @Transactional
    public Integer saveMenuRole(Map<String, Object> map) {
        List<Object> menuIdList = (List) map.get("menuIdList");
        String roleId = String.valueOf(map.get("roleId"));
        List<Map<String, Object>> list = new ArrayList<>();
        for (Object s : menuIdList) {
            Map<String, Object> m = new HashMap<>();
            m.put("menuId", Integer.valueOf(s.toString()));
            m.put("roleId", roleId);
            list.add(m);
        }
        roleMapper.deleteMenuRole(roleId);
        return roleMapper.saveMenuRole(list);
    }

    @Override
    public List<Integer> queryMenuByRole(String roleId) {
        return roleMapper.queryMenuByRole(roleId);
    }

    @Override
    public List<Integer> queryButtonByRole(String roleId) {
        return roleMapper.queryButtonByRole(roleId);
    }

    @Override
    public List<Integer> queryUserByRole(String roleId) {
        return roleMapper.queryUserByRole(roleId);
    }

    @Override
    public void bindUserToRole(Map<String, Object> map) {
        List<Object> userIdList = (List) map.get("userIdList");
        String roleId = String.valueOf(map.get("roleId"));
        for (Object userId : userIdList) {
            Integer count = roleMapper.queryRoleByUser(String.valueOf(userId), roleId);
            if (count == 0) {
                roleMapper.saveUserToRole(String.valueOf(userId), roleId);
            }
        }
    }
}
